﻿using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using RedandBlue.Common;
using RedandBlue.RepositoryPattern.Infrastructure;

namespace QuickPrompt.DomainModel.Identity
{
    public class User : IdentityUser, IObjectState, IEntityBase//IdentityUser<int, UserLogin, UserRole, UserClaim>
    {
        public User()
        {
            QuickNotes = new List<QuickNote>();
            Id = UniversalId.SequentialGuid().ToString();
        }


        //[Column(Order = 1), DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        //public int UserId { get; set; }

        [Key, Column(Order = 2)]
        public override sealed string Id { get; set; }

        [Column(Order = 3),
         Required(ErrorMessage = "{0} is required"),
         RegularExpression(@"^\p{L}+(\s+\p{L}+)*$", ErrorMessage = "Invalid {0}"),
         StringLength(50, MinimumLength = 2, ErrorMessage = "Min {1} - Max {0} characters is required"),
         Display(Name = "First Name")]
        public string FirstName { get; set; }
        [Column(Order = 4),
        Required(ErrorMessage = "{0} is required"),
        RegularExpression(@"^\p{L}+(\s+\p{L}+)*$", ErrorMessage = "Invalid {0}"),
        StringLength(50, MinimumLength = 2, ErrorMessage = "Min {1} - Max {0} characters is required"),
        Display(Name = "Last Name")]
        public string LastName { get; set; }

        [Column(Order = 5),
        Required(ErrorMessage = "{0} is required"),
        RegularExpression("^[a-zA-Z][a-zA-Z0-9]*$", ErrorMessage = "Invalid {0}"),
        StringLength(15, MinimumLength = 5, ErrorMessage = "Min {1} - Max {0} characters is required"),
        Index(IsUnique = true),
        Display(Name = "User Name")]
        public override string UserName { get; set; }

        /// <summary>
        /// <para>
        /// At least one lower case letter, At least one upper case letter, At least special character, At least one number, At least 8 characters length
        /// </para>
        /// </summary>
        [Column(Order = 6),
        //Required(ErrorMessage = "{0} is required"),
        RegularExpression(@"^.*(?=.{8,})(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[!*@#$%^&+=]).*$", ErrorMessage = "Invalid {0}"),
        Display(Name = "Password"),
        NotMapped]
        public string Password { get; set; }

        [NotMapped]
        public string ConfirmPassword { get; set; }
        [Column(Order = 7)]
        public override string PasswordHash { get; set; }
        [Column(Order = 8)]
        public string PasswordSalt { get; set; }
        [Column(Order = 9)]
        public bool Locked { get; set; }
        [Column(Order = 10)]
        public int IsAdmin { get; set; }
        [Column(Order = 11)]
        public string RegisteredIpAddress { get; set; }

        [NotMapped]
        public bool RememberMe { get; set; }

        public ICollection<QuickNote> QuickNotes { get; set; }

        #region Base Properties
        [Editable(false), ScaffoldColumn(false)]
        public DateTime DateCreatedUtc { get; set; } = DateTime.UtcNow;
        [Editable(false), ScaffoldColumn(false)]
        public DateTime LastUpdatedUtc { get; set; } = DateTime.UtcNow;
        [Editable(false), ScaffoldColumn(false)]
        public int? UpdatedByUserId { get; set; }
        [Editable(false), ScaffoldColumn(false)]
        public string LastActivityIpAddress { get; set; }
         [Editable(false), ScaffoldColumn(false)]
        public bool IsActive { get; set; }
        [Editable(false), ScaffoldColumn(false)]
        public bool IsDeleted { get; set; }

        [NotMapped]
        [Editable(false), ScaffoldColumn(false)]
        public ObjectState ObjectState { get; set; }

        #endregion



        public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<User> manager)
        {
            // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
            var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
            // Add custom user claims here
            return userIdentity;
        }
    }
}
